﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Widgetsphere.Generator.Models;
using Gravitybox.Controls.Wizard;
using Widgetsphere.Generator.Common.GeneratorFramework;

namespace Widgetsphere.Generator.Forms
{
	public partial class NewModelWizardForm : Form
	{
		#region Class Members

		private WidgetsphereGeneratorProject _tempGeneratorProject = null;
		private ProgressForm _progressForm = null;

		#endregion

		#region Constructors

		public NewModelWizardForm()
		{
			InitializeComponent();

			wizard1.BeforeSwitchPages += new Wizard.BeforeSwitchPagesEventHandler(wizard1_BeforeSwitchPages);
			wizard1.AfterSwitchPages += new Gravitybox.Controls.Wizard.Wizard.AfterSwitchPagesEventHandler(wizard1_AfterSwitchPages);
			wizard1.Finish += new EventHandler(wizard1_Finish);
			cmdImport.Click += new EventHandler(cmdImport_Click);
			lblWelcome.Text = "The nHydrate model wizard will walk you through the process of creating a new model. You can create a new model from an existing database if you wish. This action will import all tables, fields, constraints, relationships, and defaults. From this point you can start to add metadata to your objects or create a customized model. This includes creating associative tables, adding static data, marking read-only tables, creating inheritance hierarchies, etc. This wizard will only start you down the road of creating a model. Most of the setup of a model needs to be assigned in the provided designer. You can open a model's designer at any time by double-clicking a model in the VS.NET Project Explorer.";
		}

		public NewModelWizardForm(ModelRoot root)
			: this()
		{
			_tempGeneratorProject = new WidgetsphereGeneratorProject();
			txtCompanyName.Text = root.CompanyName;
			//txtDatabaseName.Text = root.Database.DatabaseName;
			txtProjectName.Text = root.ProjectName;
			txtCompanyAbbr.Text = root.CompanyAbbreviation;
		}

		#endregion

		#region Methods

		public IModelObjectController GetRootController()
		{
			return _tempGeneratorProject.RootController;
		}

		#endregion

		#region Event Handlers

		void wizard1_BeforeSwitchPages(object sender, Wizard.BeforeSwitchPagesEventArgs e)
		{
			WizardPage oldPage = wizard1.WizardPages[e.OldIndex];
			if (oldPage == pageMain)
			{
				if (!ValidationHelper.ValidDatabaseIdenitifer(txtCompanyName.Text) || !ValidationHelper.ValidCodeIdenitifer(txtCompanyName.Text))
				{
					MessageBox.Show(ValidationHelper.ErrorTextInvalidCompany, "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
					e.Cancel = true;
				}
				//else if (!ValidationHelper.ValidDatabaseIdenitifer(txtCompanyAbbr.Text) || !ValidationHelper.ValidCodeIdenitifer(txtCompanyAbbr.Text))
				//{
				//  MessageBox.Show(ValidationHelper.ErrorTextInvalidCompanyAbbreviation, "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
				//  e.Cancel = true;
				//}
				else if (!ValidationHelper.ValidDatabaseIdenitifer(txtProjectName.Text) || !ValidationHelper.ValidCodeIdenitifer(txtProjectName.Text))
				{
					MessageBox.Show(ValidationHelper.ErrorTextInvalidProject, "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
					e.Cancel = true;
				}
				//else if (!ValidationHelper.ValidDatabaseIdenitifer(txtDatabaseName.Text))
				//{
				//  MessageBox.Show(ValidationHelper.ErrorTextInvalidDatabase, "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
				//  e.Cancel = true;
				//}
			}

		}

		private void wizard1_AfterSwitchPages(object sender, Gravitybox.Controls.Wizard.Wizard.AfterSwitchPagesEventArgs e)
		{
			WizardPage newPage = wizard1.WizardPages[e.NewIndex];
			if (newPage == pageSummary)
			{

				StringBuilder sb = new StringBuilder();
				sb.AppendLine("Company Name: " + txtCompanyName.Text);
				sb.AppendLine("Project Name: " + txtProjectName.Text);				
				sb.AppendLine();

				//Tables
				sb.AppendLine("Imported Tables (" + listTables.CheckedItems.Count + " items)");
				foreach (Table item in listTables.CheckedItems)
				{
					sb.AppendLine("\t" + item.ToString() + " (" + item.Columns.Count + " columns)");
				}
				sb.AppendLine();

				//Views
				if (lstViews.CheckedItems.Count > 0)
				{
					sb.AppendLine("Imported Views (" + lstViews.CheckedItems.Count + " items)");
					foreach (CustomView item in lstViews.CheckedItems)
					{
						sb.AppendLine("\t" + item.ToString() + " (" + item.Columns.Count + " columns)");
					}
					sb.AppendLine();
				}

				//Stored Procedures
				if (lstStoredProcedures.CheckedItems.Count > 0)
				{
					sb.AppendLine("Imported Stored Procedures (" + lstStoredProcedures.CheckedItems.Count + " items)");
					sb.AppendLine("NOTE: Columns cannot be imported. You will need to define the columns for stored procedures if any exist.");
					foreach (CustomStoredProcedure item in lstStoredProcedures.CheckedItems)
					{
						sb.AppendLine("\t" + item.ToString() + " (" + item.Columns.Count + " columns, " + item.Parameters.Count + " parameters)");
					}
					sb.AppendLine();
				}

				txtSummary.Text = sb.ToString();
			}
		}

		private void wizard1_Finish(object sender, EventArgs e)
		{
			ModelRoot newRoot = (ModelRoot)_tempGeneratorProject.RootController.Object;
			newRoot.CompanyName = txtCompanyName.Text;			
			newRoot.ProjectName = txtProjectName.Text;
			newRoot.CompanyAbbreviation = txtCompanyAbbr.Text;

			//Remove all unchecked items

			//Tables
			List<Table> deleteTables = new List<Table>();
			deleteTables.AddRange(listTables.Items.ToArray<Table>());
			deleteTables.RemoveRange<Table>(listTables.CheckedItems.ToArray<Table>());
			newRoot.Database.Tables.RemoveRange(deleteTables);

			//Views
			List<CustomView> deleteViews = new List<CustomView>();
			deleteViews.AddRange(lstViews.Items.ToArray<CustomView>());
			deleteViews.RemoveRange<CustomView>(lstViews.CheckedItems.ToArray<CustomView>());
			newRoot.Database.CustomViews.RemoveRange(deleteViews);

			//Stored Procedures
			List<CustomStoredProcedure> deleteSPs = new List<CustomStoredProcedure>();
			deleteSPs.AddRange(lstStoredProcedures.Items.ToArray<CustomStoredProcedure>());
			deleteSPs.RemoveRange<CustomStoredProcedure>(lstStoredProcedures.CheckedItems.ToArray<CustomStoredProcedure>());
			newRoot.Database.CustomStoredProcedures.RemoveRange(deleteSPs);

			this.DialogResult = DialogResult.OK;

		}

		private void cmdImport_Click(object sender, EventArgs e)
		{
			this.Enabled = false;
			System.Windows.Forms.Application.DoEvents();

			_progressForm = new ProgressForm();
			try
			{
				_tempGeneratorProject = new WidgetsphereGeneratorProject();
				SqlSchemaToModel sstm = new SqlSchemaToModel(DatabaseConnectionControl1.ImportOptions.GetConnectionString());
				
				_progressForm.SetWindowTitle("Loading...");
				_progressForm.Show();
				sstm.Progress += new EventHandler<ProgressEventArgs>(LoadDatabaseProgress);
				sstm.GetProjectFromSqlSchema(_tempGeneratorProject, false);
				_progressForm.SetProgress(100, "");
				_progressForm.Close();
				_progressForm = null;

				ModelRoot root = (ModelRoot)_tempGeneratorProject.RootController.Object;

				//Tables				
				listTables.Items.Clear();
				foreach (Table item in root.Database.Tables.OrderBy(x => x.Name))
				{
					listTables.Items.Add(item);
				}
				listTables.SelectAll();

				//Views				
				lstViews.Items.Clear();
				foreach (CustomView item in root.Database.CustomViews.OrderBy(x => x.Name))
				{
					lstViews.Items.Add(item);
				}
				//lstViews.SelectAll();

				//Stored Procedures
				lstStoredProcedures.Items.Clear();
				foreach (CustomStoredProcedure item in root.Database.CustomStoredProcedures.OrderBy(x => x.Name))
				{
					lstStoredProcedures.Items.Add(item);
				}
				//lstStoredProcedures.SelectAll();
				
				wizard1.Next();
			}
			catch (Exception ex)
			{
				if (_progressForm != null)
				{
					_progressForm.SetProgress(100, "");
					_progressForm.Close();
					_progressForm = null;
				}

				MessageBox.Show("The connection information is invalid.", "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
			}
			finally
			{
				if (_progressForm != null)
				{
					_progressForm.SetProgress(100, "");
					_progressForm.Close();
					_progressForm = null;
				}

				this.Enabled = true;
			}

		}

		private void LoadDatabaseProgress(object sender, ProgressEventArgs e)
		{
			if (_progressForm != null)
			{
				if (e.PercentDone == 100) _progressForm.Close();
				else _progressForm.SetProgress(e.PercentDone, e.Text);
			}
		}

		private void cmdImportTableSelectAll_Click(object sender, EventArgs e)
		{
			listTables.SelectAll();
		}

		private void cmdImportTableUnselectAll_Click(object sender, EventArgs e)
		{
			listTables.UnselectAll();
		}

		private void cmdImportViewSelectAll_Click(object sender, EventArgs e)
		{
			lstViews.SelectAll();
		}

		private void cmdImportViewDeselectAll_Click(object sender, EventArgs e)
		{
			lstViews.UnselectAll();
		}

		private void cmdImportStoredProcedureSelectAll_Click(object sender, EventArgs e)
		{
			lstStoredProcedures.SelectAll();
		}

		private void cmdImportStoredProcedureDeselectAll_Click(object sender, EventArgs e)
		{
			lstStoredProcedures.UnselectAll();
		}

		#endregion

	}
}
